Road Flow Model#
In this example, we developed a process-based network flow model to simulate passenger car flows across the EU road network. For demonstration purposes and to minimise computational requirements, we randomly sampled 1,000 travel records from ETIS2010, using NUTS-3 regions to represent the origins and destinations of local trips. To simplify the road network, only motorways were included.
The model employs an iterative method to simulate the congested equilibrium flow assignment process, accounting for road capacities. A speed-flow relationship is embedded to predict variations in traffic speeds as vehicle volumes increase, incorporating maximum and minimum speed limits.
The model outputs flow patterns and associated travel costs, including tolls, vehicle operational costs, and time-equivalent costs. It also identifies trip isolations caused by network disconnectivity. While the observed disconnectivity in this demonstration results from the limited inclusion of motorways, the model can be adapted to assess disruptions caused by extreme hazards. This extension could support the analysis of network damage and connectivity loss due to climate-induced disruptions.
# HIDE CODE
from pathlib import Path
import pandas as pd
import geopandas as gpd
import json
import warnings
from collections import defaultdict
from itertools import islice
import road_flow_modelling.roads as func
warnings.simplefilter("ignore")
base_path = Path.cwd() / "inputs"
outpath = Path.cwd() / "outputs"
Read model parameters#
with open(
base_path / "flow_breakpoint_dict.json", "r"
) as f: # breakpoint of flow speed
flow_breakpoint_dict = json.load(f)
with open(base_path / "flow_cap_dict.json", "r") as f: # edge capacity
flow_capacity_dict = json.load(f)
with open(base_path / "free_flow_speed_dict.json", "r") as f: # free-flow speed
free_flow_speed_dict = json.load(f)
with open(base_path / "min_speed_cap.json", "r") as f: # minimum speed limit
min_speed_dict = json.load(f)
with open(base_path / "urban_speed_cap.json", "r") as f: # urban speed limit
urban_speed_dict = json.load(f)
Read network components (motorways only)#
Prepares the road nodes and links dataframes. TODO: Explain what each of them are and maybe some of the columns.
road_node_file = gpd.read_parquet(base_path / "etisplus_road_nodes.pq")
road_link_file = gpd.read_parquet(base_path / "etisplus_road_links.pq")
# add/initialise key columns
# road nodes
road_node_file["id"] = road_node_file["Network_Node_ID"].astype(str)
road_node_file["nd_id"] = road_node_file["Network_Node_ID"].astype(str)
# road links
road_link_file["id"] = road_link_file["Network_Edge_ID"].astype(str)
road_link_file["e_id"] = road_link_file["Network_Edge_ID"].astype(str)
road_link_file["from_id"] = road_link_file["Network_Node_A_ID"].astype(str)
road_link_file["to_id"] = road_link_file["Network_Node_B_ID"].astype(str)
road_link_file["road_classification"] = "Motorway"
road_link_file["form_of_way"] = "Dual Carriageway"
road_link_file["urban"] = 0 # suburban roads
road_link_file["average_toll_cost"] = 0 # ignore tolls
road_link_file = road_link_file.drop_duplicates(subset="e_id") # drop duplicates
road_link_file.reset_index(drop=True, inplace=True)
road_link_file.head()
| Network_Edge_ID | Manually_Added | Distance | Network_Node_A_ID | Network_Node_B_ID | Traffic_flow_trucks_2019 | Traffic_flow_trucks_2030 | geometry | id | e_id | from_id | to_id | road_classification | form_of_way | urban | average_toll_cost | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2604457 | 0 | 5.980 | 262914 | 260432 | 0 | 0 | LINESTRING (3482019.891 2730859.556, 3476692.4... | 2604457 | 2604457 | 262914 | 260432 | Motorway | Dual Carriageway | 0 | 0 |
| 1 | 1013364 | 0 | 18.559 | 262914 | 109845 | 0 | 0 | LINESTRING (3482019.891 2730859.556, 3494854.6... | 1013364 | 1013364 | 262914 | 109845 | Motorway | Dual Carriageway | 0 | 0 |
| 2 | 2604243 | 0 | 2.012 | 262911 | 109968 | 1871252 | 2513351 | LINESTRING (3393293.534 2897688.227, 3391385.3... | 2604243 | 2604243 | 262911 | 109968 | Motorway | Dual Carriageway | 0 | 0 |
| 3 | 1013595 | 0 | 4.728 | 262911 | 122766 | 1871252 | 2513351 | LINESTRING (3393293.534 2897688.227, 3397490.3... | 1013595 | 1013595 | 262911 | 122766 | Motorway | Dual Carriageway | 0 | 0 |
| 4 | 2604354 | 0 | 15.028 | 262909 | 260001 | 1038691 | 1449368 | LINESTRING (3725858.237 2258765.019, 3740417.8... | 2604354 | 2604354 | 262909 | 260001 | Motorway | Dual Carriageway | 0 | 0 |
road_link_file.explore("Traffic_flow_trucks_2030")